package com.zhuangjie.mvc.enhance.mp_query_enhance;

import com.zhaungjie.base.utils.LambdaStructureParser.LambdaStructureParser;
import com.zhaungjie.base.utils.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 赋值的路径
 *
 * @author zhuangjie
 * @date 2024/05/02
 */
public class ValueRef<TO> {
    private List<LambdaStructureParser.NAHRFunction<?, ?>> tos;

    public <IT> ValueRef<IT> to(LambdaStructureParser.NAHRFunction<TO, IT> to) {
        if (tos == null) tos = new ArrayList<>();
        tos.add(to);
        return (ValueRef<IT>) this;
    }

    public String toString() {
        if (tos == null) return "-空注入路径-";
        return tos.stream().map(LambdaStructureParser::convertToFieldName).collect(Collectors.joining("->"));
    }

    public void inject(Object injectObj, Object value) {
        if (tos == null || tos.isEmpty()) return;
        for (int i = 0; i < tos.size(); i++) {

            String fieldName = LambdaStructureParser.convertToFieldName(tos.get(i));
            if (injectObj == null) return;
            if (i == tos.size() - 1) {
                // 是否为最后一个set
                try {
                    Field field = ReflectionUtils.getField(injectObj.getClass(), fieldName);
                    Class<?> targetFieldType = field.getType();
                    Class<?> fieldValueType = value.getClass();
                    if (targetFieldType != fieldValueType) {
                        // 调用targetFieldType的静态valueOf方法将value转换为targetFieldType
                        Method valueOfMethod = targetFieldType.getMethod("valueOf", String.class);
                        // 调用valueOf方法，返回的是Object类型的结果，需要进行类型转换
                        value = valueOfMethod.invoke(null, String.valueOf(value));
                    }
                    ReflectionUtils.setFieldValue(injectObj, fieldName, value);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            } else {
                // 不是最后一个更新injectObj
                Object injectObjBack = injectObj;
                injectObj = ReflectionUtils.getFieldValue(injectObj, fieldName);
                if (injectObj == null) {
                    // 目标为空，准备设置初始值
                    try {
                        Field field = ReflectionUtils.getField(injectObjBack.getClass(), fieldName);
                        Class<?> fieldType = field.getType();
                        ReflectionUtils.setFieldValue(injectObjBack, fieldName, injectObj = fieldType.newInstance());
                    } catch (Exception e) {
                        throw new RuntimeException("ValueRef.inject 无法设置初始值！");
                    }
                }

            }

        }
    }
}
